package cn.com.fig.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.com.fig.dao.DepartmentMapper;
import cn.com.fig.sso.TokenGenerator;
import cn.com.fig.cache.CacheFactory;
import cn.com.fig.common.UuidGen;
import cn.com.fig.portal.constants.Constants;
import cn.com.fig.portal.CookieUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import cn.com.fig.common.StringMd5Util;
import cn.com.fig.mybatis.DbUtils;
import cn.com.fig.portal.ILoginService;
import cn.com.fig.portal.domain.Department;
import cn.com.fig.portal.domain.Identity;
import cn.com.fig.portal.domain.User;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 涉及用户登陆服务
 * 1、验证用户名、密码
 * 2、生成token
 * 3、加载用户信息到session：菜单、可操作按钮、岗位、身份
 * 4、验证输入得token是否有效，并返回用户session信息
 * @author eternalfig
 *
 */
@Service
public class LoginService implements ILoginService{

	Logger logger = LoggerFactory.getLogger(getClass());
	@Value("${sso.timeout}")
    private String yxq;
	
	@Autowired
	private DbUtils<User> dbUtils;
	@Autowired
	private DepartmentMapper departmentMapper;
	/**
	 * 根据用户名和密码验证系统中是否存在该用户及用户密码是否正确
	 * @param userId
	 * @param password
	 * @return：retCode ：00登陆成功；-1用户不存在；-2密码错误
	  					user{
		  					token
		  					userId
							departId
							userName
							mobile
							phone
							email
							homeAddress
							comAddress
							userPassword
							lockStatus
							userStatus
						}
	 */
	public Map loginCheck(String userId, String password) {
		User user = dbUtils.get("cn.com.fig.dao.UserMapper.get", userId);
		Map map = new HashMap();
		if(user == null){
			map.put("retCode", "-1");
			return map;
		}
		String md5 = StringMd5Util.GetMd5StrInfo(password);
		if(!md5.equals(user.getUserPassword())){
			map.put("retCode", "-2");
			return map;
		}
		map.put("retCode", "00");
		map.put("user", user);
		return map;
	}

	@Override
	public Map loadSession(HttpServletRequest req, HttpServletResponse res,String userId) {
		HashMap result = new HashMap();
//		加载user信息
		Map param = new HashMap();
		param.put("userId", userId);
		User user = dbUtils.get("cn.com.fig.dao.UserMapper.get", userId);
//		加载部门信息
		Department department = departmentMapper.get(user.getDepartId());
//		加载身份信息
		List<Map<String,Object>> identityList = dbUtils.queryList("cn.com.fig.dao.UserIdentityMapper.listWithUserId", param);
//		未分配岗责和身份信息
		if(identityList == null || identityList.isEmpty())
			return null;

		List<Identity> list  = new ArrayList<Identity>();
		for(Map<String,Object> map : identityList){
			if("0".equals((String)map.get("identityStatus"))){
				continue;
			}
			Identity identity = new Identity();
			identity.setDepartId((String)map.get("departId"));
			identity.setGroupId((String)map.get("groupId"));
			identity.setIdentityId((String)map.get("identityId"));
			identity.setIdentityName((String)map.get("identityName"));
			identity.setIdentityStatus((String)map.get("identityStatus"));
			identity.setMainPage((String)map.get("mainPage"));			
			list.add(identity);
			if("1".equals((String)map.get("primaryMark"))){
				user.setFirstIdentity(identity);
				user.setCurrentIdentity(identity);
			}
		}
		user.setDepartment(department);
		user.setIdentityList(list);
//		加载菜单信息
		param.clear();
		param.put("priviStatus", "1");
		param.put("identityId", user.getFirstIdentity().getIdentityId());
		List<Map<String,Object>> menuList = dbUtils.queryList("cn.com.fig.dao.IdenpriMapper.list", param);
		String sessionid = UuidGen.genUUID();
		String token = TokenGenerator.getInstance().gen(userId, yxq,sessionid);
//		设置cookie
        CookieUtil.setCookie(res, Constants.TOKEN_COOKIE_NAME,token,false,yxq);
		CookieUtil.setCookie(res, Constants.SESSION_ID,sessionid,false,yxq);
//		设置httpResponse header头
		res.setHeader(Constants.TOKEN_COOKIE_NAME,token);
		res.setHeader(Constants.SESSION_ID,sessionid);
		result.put("user",user);
		result.put("menuList",menuList);
//		保存用户相关信息至缓存中，替代session方案
		CacheFactory.getICache().put(sessionid,result);
		return result;
	}

	@Override
	public Map identityChange(HttpServletRequest req, HttpServletResponse res, String userId,String identityId) {
		Map result = this.tokenCheck(req,res,userId,getToken(req),getSessionid(req));
		User user = dbUtils.get("cn.com.fig.dao.UserMapper.get", userId);
		Map param = new HashMap();
		param.put("identityId", identityId);
//		加载身份信息
		List<Map<String,Object>> identityList = dbUtils.queryList("cn.com.fig.dao.UserIdentityMapper.list", param);
		for(Map<String,Object> map : identityList){
			if("0".equals((String)map.get("identityStatus"))){
				continue;
			}
			Identity identity = new Identity();
			identity.setDepartId((String)map.get("departId"));
			identity.setGroupId((String)map.get("groupId"));
			identity.setIdentityId((String)map.get("identityId"));
			identity.setIdentityName((String)map.get("identityName"));
			identity.setIdentityStatus((String)map.get("identityStatus"));
			identity.setMainPage((String)map.get("mainPage"));
			user.setCurrentIdentity(identity);
		}
//		加载菜单信息
		param.clear();
		param.put("priviStatus", "1");
		param.put("identityId", user.getCurrentIdentity().getIdentityId());
		List<Map<String,Object>> menuList = dbUtils.queryList("cn.com.fig.dao.IdenpriMapper.list", param);
		result.put("menuList",menuList);
		return result;
	}

	@Override
	public Map tokenCheck(HttpServletRequest req, HttpServletResponse res,String userId,String token,String sessionid) {
		User user = dbUtils.get("cn.com.fig.dao.UserMapper.get", userId);
		Map map = new HashMap();
		if(user == null){
			return null;
		}

        if(TokenGenerator.getInstance().checkToken(userId,token)){
			Map result = (Map) CacheFactory.getICache().get(sessionid);
			if(result == null)
				result = this.loadSession(req,res,userId);
			return result;
		}
		return null;
	}
	@Override
	public void clearSession(HttpServletRequest req){
//		首先从http header中获取sessionid，通常桌面软件会把sessionid放到header中发送服务器端
		String sessionid = req.getHeader(Constants.SESSION_ID);
		if(sessionid == null) {
//		    其次可以从cookie中获取sessionid信息，一般通过浏览器访问时，sessionid会放在cookie中
			sessionid = CookieUtil.getTokenFromCookie(req, Constants.SESSION_ID);
		}
		if(sessionid != null)
			CacheFactory.getICache().remove(sessionid);
	}

    @Override
    public String getToken(HttpServletRequest req) {
//        		首先从http header中获取token，通常桌面软件会把token放到header中发送服务器端
        String token = req.getHeader(Constants.TOKEN_COOKIE_NAME);
        if(token == null) {
//		    其次可以从cookie中获取token信息，一般通过浏览器访问时，token会放在cookie中
            token = CookieUtil.getTokenFromCookie(req, Constants.TOKEN_COOKIE_NAME);
        }
        return token;
    }

    @Override
    public String getSessionid(HttpServletRequest req) {
        String sessionid = req.getHeader(Constants.SESSION_ID);
        if(sessionid == null) {
            sessionid = CookieUtil.getTokenFromCookie(req, Constants.SESSION_ID);
        }
        return sessionid;
    }
}
